package ThreadDemo.ThreadDemo7;

/**
 * Created with IntelliJ IDEA.
 * Description: 自己设计一个阻塞队列
 * User:周次煜
 * Date: 2024-07-25
 * Time：20:20
 */


public class MyBlockingQueue {
    // 元素数组
    private int val ;

    // 存在的元素大小
    private int size;


    // 记录头元素和尾元素
   private  int head ;

   private int tail ;

    // 数组存储
    private int[] nums;

    //  给数组创建空间
    public MyBlockingQueue(int len) {
        nums = new int[len];
        tail= 0;
        head = 0;
    }


    // 入队列
    public  void put(int val) throws InterruptedException {

        synchronized(this) {
            //        数组满的情况
            while(size == nums.length) {
//                循环判断，防止 wait 被其他唤醒
                this.wait() ;
            }

//        添加元素
            nums[tail] = val;
            tail++;

//        元素个数增加
            size++;

//        防止越界
            if(tail == nums.length) {
                tail = 0;
            }

            // 唤醒为 空 的情况
            this.notify();
        }
    }


//    出队列
    public int  take() throws InterruptedException {

        // 加锁 线程安全
        synchronized(this) {
            // 数组为 空的情况
            while(size == 0) {
//                循环判断，防止 wait 被其他唤醒
                this.wait() ;
            }

            int ret = nums[head];

            head++;
            size--;

//        防止越界
            if(head == nums.length) {
                head = 0;
            }


            // 唤醒数组满的情况
            this.notify();


            return ret;
        }
    }


}


class Test {
    public static void main(String[] args) throws InterruptedException {

//        制造一个生产者消费者模型
        MyBlockingQueue queue = new MyBlockingQueue(1);




        // 生产
      Thread in = new Thread(()->{
          for (int i = 0; i < 100 ; i++) {
              try {
                  System.out.println("生产个数: "+ i);
                  Thread.sleep(1000);
                  queue.put(i);
              } catch (InterruptedException e) {
                  throw new RuntimeException(e);
              }

          }


      });


      // 消费
        Thread out = new Thread(()->{
            for (int i = 0; i < 100 ; i++) {
                try {
                   int tmp  = queue.take();
                    System.out.println("消费个数: "+ tmp);
                    Thread.sleep(1000);


                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        in.start();
        out.start();

        in.join();
        out.join();

    }
}



